/*
 *  Copyright 2019-2020 Fang Jin Biao
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.admin.system.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.collections4.CollectionUtils;
import org.dozer.Mapper;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.admin.system.model.MenuModel;
import com.admin.system.service.IMenuService;
import com.admin.utils.DozerUtils;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import me.zhengjie.annotation.Log;
import me.zhengjie.exception.BadRequestException;
import me.zhengjie.modules.system.service.dto.MenuDto;
import me.zhengjie.modules.system.service.dto.MenuQueryCriteria;
import me.zhengjie.utils.PageUtil;
import me.zhengjie.utils.SecurityUtils;

/**
 * @author adyfang
 * @date 2020年5月2日
 */
@Api(tags = "系统：菜单管理")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/menus")
public class AdminMenuController {
	private final IMenuService menuService;

	private final Mapper mapper;

	private static final String ENTITY_NAME = "menu";

	@Log("导出菜单数据")
	@ApiOperation("导出菜单数据")
	@GetMapping(value = "/download")
	@PreAuthorize("@el.check('menu:list')")
	public void download(HttpServletResponse response, MenuQueryCriteria criteria) throws IOException {
		menuService.download(menuService.queryAll(criteria, false), response);
	}

	@ApiOperation("获取前端所需菜单")
	@GetMapping(value = "/build")
	public ResponseEntity<Object> buildMenus() {
		List<MenuDto> menuDtoList = menuService.findByUser(SecurityUtils.getCurrentUserId());
		List<MenuDto> menuDtos = menuService.buildTree(menuDtoList);
		return new ResponseEntity<>(menuService.buildMenus(menuDtos), HttpStatus.OK);
	}

	@ApiOperation("返回全部的菜单")
	@GetMapping(value = "/lazy")
	@PreAuthorize("@el.check('menu:list','roles:list')")
	public ResponseEntity<Object> getMenus(@RequestParam Long pid) {
		return new ResponseEntity<>(menuService.getMenus(pid), HttpStatus.OK);
	}

	@Log("查询菜单")
	@ApiOperation("查询菜单")
	@GetMapping
	@PreAuthorize("@el.check('menu:list')")
	public ResponseEntity<Object> getMenus(MenuQueryCriteria criteria) throws Exception {
		List<MenuDto> menuDtoList = menuService.queryAll(criteria, true);
		return new ResponseEntity<>(PageUtil.toPage(menuDtoList, menuDtoList.size()), HttpStatus.OK);
	}

	@Log("查询菜单")
	@ApiOperation("查询菜单:根据ID获取同级与上级数据")
	@PostMapping("/superior")
	@PreAuthorize("@el.check('menu:list')")
	public ResponseEntity<Object> getSuperior(@RequestBody List<Long> ids) {
		Set<MenuDto> menuDtos = new LinkedHashSet<>();
		if (CollectionUtils.isNotEmpty(ids)) {
			for (Long id : ids) {
				MenuDto menuDto = menuService.findById(id);
				menuDtos.addAll(menuService.getSuperior(menuDto, new ArrayList<>()));
			}
			return new ResponseEntity<>(menuService.buildTree(new ArrayList<>(menuDtos)), HttpStatus.OK);
		}
		return new ResponseEntity<>(menuService.getMenus(null), HttpStatus.OK);
	}

	@Log("新增菜单")
	@ApiOperation("新增菜单")
	@PostMapping
	@PreAuthorize("@el.check('menu:add')")
	public ResponseEntity<Object> create(@Validated @RequestBody MenuModel resources) {
		if (resources.getId() != null) {
			throw new BadRequestException("A new " + ENTITY_NAME + " cannot already have an ID");
		}
		menuService.create(resources);
		return new ResponseEntity<>(HttpStatus.CREATED);
	}

	@Log("修改菜单")
	@ApiOperation("修改菜单")
	@PutMapping
	@PreAuthorize("@el.check('menu:edit')")
	public ResponseEntity<Object> update(@Validated(MenuModel.Update.class) @RequestBody MenuModel resources) {
		menuService.update(resources);
		return new ResponseEntity<>(HttpStatus.NO_CONTENT);
	}

	@Log("删除菜单")
	@ApiOperation("删除菜单")
	@DeleteMapping
	@PreAuthorize("@el.check('menu:del')")
	public ResponseEntity<Object> delete(@RequestBody Set<Long> ids) {
		Set<MenuModel> menuSet = new HashSet<>();
		for (Long id : ids) {
			List<MenuDto> menuList = menuService.getMenus(id);
			menuSet.add(menuService.findOne(id));
			menuSet = menuService.getDeleteMenus(DozerUtils.mapList(mapper, menuList, MenuModel.class), menuSet);
		}
		menuService.delete(menuSet);
		return new ResponseEntity<>(HttpStatus.OK);
	}
}
